// Copyright 2009 Google Inc.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

#define FFMPEG_INTERNAL_BUILD
#include "avcodec_interface.h"

#include "avcodec.h"
#include "log.h"

extern "C" {
  void img_convert_init();
}

namespace {

void AvCodecLogCallback(void* ptr, int level, const char* fmt, va_list vl) {
  // Filter out ffmpeg log messages.
  // ffmpeg will use printf in its default log callback which will result in a
  // console window appearing on S60. We use this empty callback to prevent
  // this from happening.
}

class AvCodec : public AvCodecInterface {
public:
  AvCodec() {
    avcodec_init();
    avcodec_register_all();
    img_convert_init();
    av_log_set_callback(AvCodecLogCallback);
  }

  // From FfmpegInterface.
  int open(AVCodecContext* avctx, AVCodec* codec) {
    return avcodec_open(avctx, codec);
  }

  int close(AVCodecContext* avctx) {
    return avcodec_close(avctx);
  }

  int decode_audio2(AVCodecContext* avctx,
                    int16_t* samples,
                    int* frame_size_ptr,
                    uint8_t* buf,
                    int buf_size) {
    // Audio is not supported.
    return -1;
  }

  int decode_video(AVCodecContext* avctx,
                   AVFrame* picture,
                   int* got_picture_ptr,
                   uint8_t* buf,
                   int buf_size) {
    return avcodec_decode_video(avctx, picture, got_picture_ptr, buf, buf_size);
  }

  AVCodec* find_decoder(int id) {
    return avcodec_find_decoder(static_cast<CodecID>(id));
  }

  void get_context_defaults2(AVCodecContext* s, int codec_type) {
    return avcodec_get_context_defaults2(s, static_cast<CodecType>(codec_type));
  }
};

}  // namespace

AvCodecInterface::~AvCodecInterface() {
}

EXPORTED_METHOD AvCodecInterface* AvCodecInterface::Instance() {
  static AvCodecInterface* instance = NULL;
  if (!instance) {
    instance = new AvCodec;
  }
  return instance;
}
